#include "parser.h"
#include "token.h"
#include "scanner.h"
#include "parser-helper.h"

#define VOID_OP \
	__asm {int 3};

#define ERROR_CHECK(C) \
	do { \
	if( !*status ) { \
	C return NULL;}}while(0)

#define EXPECT(c) \
	do{ \
	Token _token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE); \
	assert(c == _token.token());}while(0)


namespace tinyscript{
namespace internal{

bool ParserScope::Scope::QuerySymbol( const std::string& name ) {
	for( ParserScope::ScopeChain::reverse_iterator b = (scope_->scope_stack_).rbegin() ;
		b != (scope_->scope_stack_).rend() ; ++b ) {
			ScopeVariableList& vl = (*b)->scope_variable_;
			ScopeVariableList::iterator iret = 
				vl.find(name);
			if( iret != vl.end() ) {
				return true;
			}
	}
	return false;
}

bool ParserScope::Scope::DecSymbol( const std::string& name ) {
	std::pair< ScopeVariableList::iterator, bool > iret = scope_variable_.insert(name);
	return iret.second;
}

}// namespace internal
}// namespace script




namespace tinyscript{
namespace internal{

Parser::Parser( Scanner& scanner ) :
scanner_(scanner){
	ASNode::BindASNodePage(&node_page_);
}

Parser::~Parser() {
	ASNode::ClearASNodePage();
}

void Parser::ReportError( const std::string& err ) {
	error_description_.resize(1024);
	int size = sprintf(tinyscript::util::StringAsArray(&error_description_),"Scanner:%s",err.c_str());
	error_description_.resize(size);
	__asm int 3
}

}// namespace internal
}// namespace sscript

namespace tinyscript{
namespace internal{

// When a local variable meets, there exists 3 possible situation 1) Function invoking ,
// 2) List access 3) Variable itself. This function will parse each possible situation 
// and return the right node
ASNode* Parser::ParseSymbol( const Token& tk , bool* status ) {
	Token ntk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	switch( ntk.token() ) {
	case Token::TT_LSBRACKET:
		return ParseFunctionInvoke(tk,status);
	case Token::TT_LMBRACKET:
	case Token::TT_DOT:
		return ParseListAccessor(tk,status);
	default:
		return new NodeSymbol( tk.GetSymbolName(scanner_.buffer()) );
	}
}
// Parsing the unary statements.
// The unary statements will always starts with an unary operator.
// An unary operator is TT_NOT:! TT_ADD:+ TT_SUB:-
ASNode* Parser::ParseUnary( const Token& tk , bool* status ) {
	assert( ParserHelper::IsUnaryOperator(tk.token()) );
	ParsingTerminator terminator;
	*status = true;
	// 1. Get unary operator
	NodeUnary* unary_operator = new NodeUnary();
	unary_operator->set_operation(tk.token());
	// 2. Get operand
	Token token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	ASNode* operand = ParseOperand(token,status);
	ERROR_CHECK(delete unary_operator;);
	unary_operator->set_child(operand);
	return unary_operator;
}

// A function invoke is something like this:
// foo(1+2,var3,%gvar3%,4*7)
ASNode* Parser::ParseFunctionInvoke( const Token& tk , bool* status ) {
	assert( tk.token() == Token::TT_SYMBOL );
	ParsingTerminator terminator;
	*status = true;
	// 1) Build function name
	NodeFuncInvoke * invoke_node = new NodeFuncInvoke();
	invoke_node->set_func_name( tk.GetSymbolName(scanner_.buffer()) );
	// 2) Get the function invoking parameter list
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() != Token::TT_LSBRACKET ) {
		*status = false;
		ReportError("Expect \"(\"!");
		return NULL;
	}
	// 3) Start to parse all the invoking parameters 
	terminator.AddTerminator( Token::TT_COMMA );
	terminator.AddTerminator( Token::TT_RSBRACKET );
	while ( true ) {
		ASNode* child_node = ParseExpression( terminator , status );
		ERROR_CHECK(delete invoke_node;);
		// Append the child into the parameter list
		invoke_node->AppendChild( child_node );
		// The parsing status is totally OK. Which means the return node is a
		// valid expression node. Here we will check how the ParseExpression
		// terminates by terminator. If it terminates because of a comma , just
		// continue, if it terminates because of ')' , stop parsing the function
		// invoking.
		if( terminator.last_terminator().token() == Token::TT_RSBRACKET ) {
			break;
		}
	}
	return invoke_node;
}

// Parsing the atomic value.
// The atomic value is : int, float, string, symbol, function invoke,
// list accessor.
ASNode* Parser::ParseAtomicValue( const Token& tk , bool* status ) {
	*status = true;
	switch(tk.token()) {
	case Token::TT_INT:
		// Int 
		return new NodeInt(tk.GetTokenValue<int>(scanner_.buffer()));
	case Token::TT_FLOAT:
		// Float
		return new NodeFloat(tk.GetTokenValue<double>(scanner_.buffer()));
	case Token::TT_TRUE:
		return new NodeBoolean(true);
	case Token::TT_FALSE:
		return new NodeBoolean(false);
	case Token::TT_STRING:
		return new NodeString( tk.GetTokenValue<std::string>(scanner_.buffer()) );
	case Token::TT_SYMBOL:
		// Symbol
		// The symbol choice has several possibility
		// it can be list access , function invoking
		// or just variable dereference
		return ParseSymbol(tk,status);
	default:
		*status = false;
		return NULL;
	}
}

// Operand := Int | Float | String | Symbol | Unary | Expression
ASNode* Parser::ParseOperand( const Token& tk , bool* status ) {
	*status = true;
	ASNode* ret = ParseAtomicValue(tk,status);
	if( !*status ) {
		if( tk.token() == Token::TT_LSBRACKET ) {
			ParsingTerminator terminator;
			terminator.AddTerminator(Token::TT_RSBRACKET);
			ASNode* exp = ParseExpression(terminator,status);
			ERROR_CHECK(VOID_OP);
			EXPECT(Token::TT_RSBRACKET);
			return exp;
		} else if( ParserHelper::IsUnaryOperator(tk.token()) ) {
			return ParseUnary(tk,status);
		} else {
			ReportError("Expect operand.");
			*status = false;
			return NULL;
		}
	}
	return ret;
}

// Parsing the expression statements. 
// A statements contains binary operation , unary operation 
// and also function invocation and list location.
ASNode* Parser::ParseExpression( const ParsingTerminator& term , bool* status ){
	Token tk = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	ParsingTerminator terminator;
	// Except the first variable should be located at the left hand side of an operator , all the later on
	// expression should be the right hand side child of operator with some priority adjusting
	ASNode* first_lhs = ParseOperand(tk,status);
	if( !*status ) {
		// Check weather this is a EMPTY expression. 
		if( term.Decide(tk) ) {
			*status = true;
			// The expression will not CONSUME the termination
			// character. Instead of just ignoring it, this function
			// will put the terminator character back to the stream
			scanner_.PutBack( tk );
			return new NodeKeyword(Token::TT_PASS);
		}
		return NULL;
	}
	// If we reach here, it means that our left hand side node is ok
	// Later on, we can meet an binary operator , end or error .
	NodeExpression* op_node = NULL;
	tk = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	if( ParserHelper::IsBinaryOperator(tk.token()) ) {
		op_node = new NodeExpression();
		op_node->set_left_child(first_lhs);
		op_node->set_opreation(tk.token());
	} else {
		// Here I need to decide weather the parsing
		// process should be terminated
		if( term.Decide(tk) ) {
			*status = true;
			// The expression will not CONSUME the termination
			// character. Instead of just ignoring it, this function
			// will put the terminator character back to the stream
			scanner_.PutBack( tk );
			return first_lhs;
		} else {
			*status = false;
			delete first_lhs;
			ReportError("Expect binary operator!");
			return NULL;
		}
	}
	// If we reach here, it means that we can 
	// continue searching the right hand side variable
	ASNode* rhs = NULL;
	while( true ) {
		// 1. Get the right hand side operand
		tk = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
		rhs = ParseOperand(tk,status);
		ERROR_CHECK(delete op_node;);
		op_node->set_right_child(rhs);
		// Move the op node to top 
		if( op_node->parent() != NULL ) {
			// I just need to move up once , since only 2 level of priority exists
			// If have multiple priority, the algorithm should change 
			op_node = op_node->parent()->EnsureCast<NodeExpression>();
		}
		// 2. Get the operator on top of it
		tk = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
		if( term.Decide(tk) ) {
			*status = true;
			// The expression will not CONSUME the termination
			// character. Instead of just ignoring it, this function
			// will put the terminator character back to the stream
			scanner_.PutBack( tk );
			return op_node;
		} 
		// We only accept the binary operator or failed
		if( ParserHelper::IsBinaryOperator(tk.token()) ) {
			NodeExpression* cur_op_node = new NodeExpression();
			cur_op_node->set_opreation(tk.token());
			// Here we need to adjust the priority node.
			// Simply puts we will rotate some tree nodes
			// and make all node's has lower priority than
			// its child node.
			//      +
			//     / \
			//    /   \
			//   1     2
			// Once a *3 adds inside of the stream,
			// The tree should be adjusted to :
			//      +
			//     / \
			//    /   \
			//   1     *
			//        / \
			//       /   \
			//      2     4
			int parent_priority = ParserHelper::GetPriority( op_node->opreation());
			int current_priority = ParserHelper::GetPriority( tk.token() );
			if( current_priority > parent_priority ) { 
				// Now we need to adjust the node 
				cur_op_node->set_left_child( op_node->right_child() );
				op_node->set_right_child( cur_op_node );
				// Modify the op_node to let the next operand to be inserted at the right
				// position. The modification of op_node will be completed once the operand
				// been inserted into the tree
				op_node = cur_op_node;
			} else {
				cur_op_node->set_left_child(op_node);
				op_node = cur_op_node;
			}
		} else {
			// Error comes here.
			*status = false;
			delete op_node;
			ReportError("Expect binary operator!");
			return NULL;
		}
	}

}
// List accessor:
// Symbol[Expression]
// Symbol.(Expression)
// Symbol.AtmoicValue
ASNode* Parser::ParseListAccessor( const Token& tk , bool* status ) {
	assert( tk.token() == Token::TT_SYMBOL );
	ParsingTerminator terminator;
	// 1. Set the list name
	NodeListAccessor* accessor = new NodeListAccessor();
	ASNode* index = NULL;
	accessor->set_name(tk.GetSymbolName(scanner_.buffer()));
	// 2. Find the [ or .
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() == Token::TT_LMBRACKET ) {
		// The user will use [] as operator , just call
		// ParseExpression to fetch the index node and 
		// terminates when a ] meets.
		terminator.AddTerminator( Token::TT_RMBRACKET );
		index = ParseExpression(terminator,status);
		ERROR_CHECK(delete accessor;);
		EXPECT(Token::TT_RMBRACKET);
	} else if( token.token() == Token::TT_DOT ) {
		// The user will use . as operator. It has 2 version
		// 1. '(' means the index is an expression.
		// 2. The variable comes or atomic value comes, it means
		// it is not an expression usage. 
		// Others are errors.
		Token ntk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
		if( ntk.token() == Token::TT_LSBRACKET ) {
			terminator.AddTerminator(Token::TT_RSBRACKET);
			index = ParseExpression(terminator,status);
			ERROR_CHECK(delete accessor;);
			EXPECT(Token::TT_RSBRACKET);
		} else {
			// Try to parse it as an atomic value
			// ParseAtomicValue requires the scanner has consumes the
			// this indicator token , so a call of Advance is needed
			token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
			if( token.token() != Token::TT_SYMBOL ) {
				// Only symbol allowed once the user use dot to 
				// access the element of list without a "(" ")"
				*status = false;
				delete accessor;
				ReportError("Expect symbol here.");
				return NULL;
			}
			index = new NodeSymbol(token.GetSymbolName(scanner_.buffer()));
		}
	}
	// Once we reach here the index should have been initialized
	// properly. Just set the index to the accessor's index node
	accessor->set_index_node(index);
	*status = true;
	return accessor;
}

// Another long name function, but it really tells us what it means.
// This function is used to parse the variable declaration _OR_ 
// simply left hand side value. The most fundamental different
// between declaration of var and lhs value is that declaration
// need to test the variable scope and do registration. But the
// lhs value , although it may be global value , however it just
// need to do the declaration instead of testing its existence .

ASNode* Parser::ParseVarDeclarationOrLeftHandSideValue(  bool* status ) {
	*status = true;
	// var|optional decorator|optional symbol_name
	NodeVarDeclaration* lfs_var = NULL;
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	// This flag is used to indicates weather we are parsing
	// an real declaration or just an left hand side variable
	// for assignment. A declaration can also be left hand side
	// variable for assignment .
	bool lhs = true;
	// This can be a const decorator or omit it means
	// that it is a mutable variable, definitely, it can be
	// mutable key word as well.
	// Now we check the var operator
	if( token.token() == Token::TT_VAR ) {
		if( lfs_var == NULL )
			lfs_var = new NodeVarDeclaration();

		lfs_var->set_decorator(token.token());
		token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
		lhs = false;
	} else if( token.token() == Token::TT_GLOBAL ) {
		token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	}
	// This token must be an symbol
	if( token.token() != Token::TT_SYMBOL ) {
		delete lfs_var;
		*status = false;
		ReportError("Expect symbol.");
		return NULL;
	}
	if( lhs ) {
		assert( lfs_var == NULL );
		// Here we cannot test weather this symbol is existed, since
		// even if we cannot find it in our scope chain, it can be
		// a global variable which has the same syntax. The existence
		// of variable can only be tested once the code executes.
		return new NodeSymbol( token.GetSymbolName(scanner_.buffer()) );
	} else {
		// This branch means it MUST BE a declaration , no matter
		// it follows an assignment or not . So we need to  check
		// the symbol is existed or not !!!
		// If is existed, this means an error occurs, otherwise
		// we should push this variable/symbol name into the 
		// scope to avoid redefinition
		std::string symbol_name( token.GetSymbolName(scanner_.buffer()) );
		if(scope_.CurrentScope()->QuerySymbol(symbol_name)) {
			ReportError("Redefine symbol!");
			delete lfs_var;
			*status = false;
			return NULL;
		} else {
			scope_.CurrentScope()->DecSymbol(symbol_name);
		}
		lfs_var->set_name( symbol_name ) ;
		return lfs_var;
	}
}

ASNode* Parser::ParseConditionAndBody( ASNode** condition , ASNode** body , bool* status ) {
	*status = true;
	// Expecting the '(' to parse the condition string
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() == Token::TT_LSBRACKET ) {
		ParsingTerminator terminator;
		terminator.AddTerminator( Token::TT_RSBRACKET );
		// Parsing the condition based on the specific requirements
		*condition = ParseExpression(terminator,status);
		ERROR_CHECK(VOID_OP);
		EXPECT(Token::TT_RSBRACKET);
	} else {
		ReportError("Expected \"(\".");
		*status = false;
		return NULL;
	}
	// Expecting the '{'
	// Instead of using Advance, we use peek here, this is because
	// the code block NEED to have '{' to indicates it is starting
	// However the ParseExpression doesn't needs this,it simply use
	// terminator to tell where to stop.
	token = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() == Token::TT_LLBRACKET ) {
		*body = ParseChunk(status);
		ERROR_CHECK(VOID_OP);
	}
	return NULL;
}

// If
// Parsing if is kind of easy. After parsing the main block of
// if, what needed is parsing elseif and else, however all of 
// these sentence is optional.
ASNode* Parser::ParseIf( const Token& tk , bool* status ) {
	*status = true;
	assert(tk.token() == Token::TT_IF);
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	*status = true;
	ASNode* condition;
	ASNode* body;
	ParseConditionAndBody(&condition,&body,status);
	ERROR_CHECK(VOID_OP);
	NodeIf* ret = new NodeIf();
	ret->set_body(body);
	ret->set_condition_node( condition );
	// Parsing the elseif / else branch
	while( true ) {
		// The usage of peek is because the next token can be other token
		// except "else" or "elseif". If meets some other token, this means
		// that the If parsing should terminates. 
		token = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
		if( token.token() == Token::TT_ELSE ) {
			// Parsing else
			ASNode* else_branch = ParseElse(status);
			ERROR_CHECK(VOID_OP);
			ret->AppendBranch(else_branch);
			break;
		} else if( token.token() == Token::TT_ELSEIF ) {
			// Parsing elseif
			ASNode* elseif_branch = ParseElseIf(status);
			ERROR_CHECK(VOID_OP);
			ret->AppendBranch(elseif_branch);
		} else {
			break;
		}
	}
	return ret;
}
ASNode* Parser::ParseElseIf( bool* status ) {
	*status = true;
	Token token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	assert( token.token() == Token::TT_ELSEIF );
	ASNode* condition;
	ASNode* body;
	ParseConditionAndBody(&condition,&body,status);
	ERROR_CHECK(VOID_OP);
	NodeElseIf* elseif_node = new NodeElseIf();
	elseif_node->set_body(body);
	elseif_node->set_condition_node(condition);
	return elseif_node;
}
ASNode* Parser::ParseElse( bool* status ) {
	*status = true;
	Token token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	assert( token.token() == Token::TT_ELSE );
	ASNode* body;
	token = scanner_.Peek(Scanner::MODE_IGNORE_WHITESPACE);
	if( token.token() == Token::TT_LLBRACKET ) {
		ParsingTerminator terminator;
		terminator.AddTerminator(Token::TT_RLBRACKET);
		body = ParseChunk(status);
		ERROR_CHECK(VOID_OP);
	}
	NodeElse* else_node = new NodeElse();
	else_node->set_body(body);
	return else_node;
}
ASNode* Parser::ParseFor_Init( bool* status ) {
	// For the init part, it can be a assignment 
	// or a expression.
	ParsingTerminator term;
	term.AddTerminator(Token::TT_END);
	ASNode* ret = ParseVarDeclarationOrWithAssignment(term,status);
	if( !*status ) {
		ParsingTerminator terminator;
		terminator.AddTerminator(Token::TT_END);
		ret = ParseExpression(terminator,status);
		ERROR_CHECK(VOID_OP);
		// Expression
		return ret;
	}
	// Assignment
	return ret;
}
ASNode* Parser::ParseFor_Condition( bool* status ) {
	ParsingTerminator terminator;
	terminator.AddTerminator( Token::TT_END );
	return ParseExpression(terminator,status);
}
ASNode* Parser::ParseFor_Step( bool* status ) {
	ParsingTerminator term;
	term.AddTerminator(Token::TT_RSBRACKET);
	// Must be an assignment
	return ParseVarDeclarationOrWithAssignment(term,status);
}
ASNode* Parser::ParseFor( const Token& tk , bool* status ) {
	*status = true;
	assert(tk.token() == Token::TT_FOR);
	Token token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	NodeFor* ret = new NodeFor();
	ASNode* start;
	ASNode* condition;
	ASNode* step;
	ASNode* body;

	if( token.token() != Token::TT_LSBRACKET ) {
		*status = false;
		return NULL;
	}
	// 1. Parse the start/condition/step entry for
	// For statements. Since for each start/condition/step,
	// the Expression is allowed to be empty(as C), so we
	// use ParseExpressionAllowEmpty function to parse 
	// each entry.
	start = ParseFor_Init(status);
	ERROR_CHECK(delete ret;);
	ret->set_initial_node(start);
	EXPECT(Token::TT_END);

	condition = ParseFor_Condition(status);
	ERROR_CHECK(delete ret;);
	ret->set_condition_node(condition);
	EXPECT(Token::TT_END);

	// Parsing the step, however the step terminator is 
	// ')' instead of ;
	step = ParseFor_Step(status);
	ERROR_CHECK(delete ret;);
	ret->set_step_node(step);
	EXPECT(Token::TT_RSBRACKET);

	// 2. Parse the For loop body. This parsing requires usage of
	// ParseCodeBlock function. This function will guarantee return
	// an no empty block even if user doesn't specify any code inside
	// of the block. 
	token = scanner_.Peek(Scanner::MODE_IGNORE_WHITESPACE);
	if( token.token() != Token::TT_LLBRACKET ) {
		// Error here. 
		// This is not allowed !
		ReportError("Expected \"{\"");
		delete ret;
		return NULL;
	}
	body = ParseChunk(status);
	ERROR_CHECK(delete ret;);
	ret->set_body(body);
	return ret;
}
ASNode* Parser::ParseForeach( const Token& tk , bool* status ) {
	*status = true;
	ASNode* condition;
	ASNode* body;
	assert( tk.token() == Token::TT_FOREACH );
	ParseConditionAndBody(&condition,&body,status);
	ERROR_CHECK(VOID_OP);
	NodeForeach* ret = new NodeForeach();
	ret->set_body(body);
	ret->set_list_node(condition);
	return ret;
}
ASNode* Parser::ParseWhile( const Token& tk , bool* status ) {
	*status = true;
	ASNode* body;
	ASNode* condition;
	assert(tk.token() == Token::TT_WHILE);
	ParseConditionAndBody(&condition,&body,status);
	ERROR_CHECK(VOID_OP);
	NodeWhile* ret = new NodeWhile();
	ret->set_body(body);
	ret->set_condition_node(condition);
	return ret;
}

// A function define is something looks like this:
// function(par1,par2,par3,par4,par5) {
//  statements;
//  ...
// }
ASNode* Parser::ParseFunctionDefine( const Token& tk , bool* status ) {
	*status = true;
	assert( tk.token() == Token::TT_FUNCTION );
	Token token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	if( token.token() != Token::TT_LSBRACKET ) {
		*status = false;
		return NULL;
	}
	NodeDefineFunc* func = new NodeDefineFunc();
	// 1. Parsing the parameter lists
	while( true ) {
		// Parsing the parameter
		token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
		NodeSymbol* para = new NodeSymbol();
		para->set_variable_name( token.GetSymbolName(scanner_.buffer()) );
		func->AppendParameter(para);
		// Looking for the end
		token = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
		if( token.token() == Token::TT_RSBRACKET ) {
			break;
		} else if( token.token() != Token::TT_COMMA ) {
			delete func;
			*status = false;
			ReportError("Expected \",\" or \")\".");
			return NULL;
		}
	}
	// 2. Parsing the function body
	token = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() != Token::TT_LLBRACKET ) {
		delete func;
		*status = false;
		ReportError("Expected \"{\".");
		return NULL;
	}
	ASNode* body = ParseChunk(status);
	ERROR_CHECK(delete func;);
	func->set_body(body);
	return func;
}
// A return statement will be treated as a special statement. It
// starts with a return keyword and follows by _ONLY_ one value.
// This value can be 1) Expression 2) Function Define 3) List Define
// Simply puts it , it is a RightHandSideValue
ASNode* Parser::ParseReturn( const Token& tk , bool* status ) {
	assert( tk.token() == Token::TT_RETURN );
	*status = true;
	ParsingTerminator term;
	term.AddTerminator( Token::TT_END );
	ASNode* val = ParseRightHandSideValue(term,status);
	ERROR_CHECK(VOID_OP);
	EXPECT(Token::TT_END);
	NodeReturn* nret = new NodeReturn();
	nret->set_value(val);
	return nret;
}
// Parse a key value mapping inside of the list object
// The key/value inside of the list object should be
// like : name = dec;
// The possible name can be integer/string/symbol
ASNode* Parser::ParseListAssignment( bool* status ) {
	// Grab the symbol for the array
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	ASNode* name;
	switch( token.token() ) {
	case Token::TT_SYMBOL:
		name = new NodeSymbol( token.GetSymbolName(scanner_.buffer()) );
		break;
	case Token::TT_STRING:
		name = new NodeString( token.GetTokenValue<std::string>(scanner_.buffer()) );
		break;
	case Token::TT_INT:
		name = new NodeInt( token.GetTokenValue<int>(scanner_.buffer()) );
		break;
	default:
		ReportError("Expected int/string/symbol here.");
		*status = false;
		return NULL;
	}
	// Skip the EQ symbol
	token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() != Token::TT_ASSIGN ) {
		ReportError("Expected \"=\".");
		*status = false;
		return NULL;
	}
	ParsingTerminator term;
	term.AddTerminator( Token::TT_END );
	ASNode* rhs = ParseRightHandSideValue(term,status);
	ERROR_CHECK(delete name;);
	EXPECT( Token::TT_END );
	NodeDefineListAssignment* ret = new NodeDefineListAssignment();
	ret->set_name(name);
	ret->set_value_node( rhs );
	return ret;
}
// A List define is something like this:
// {
// qq = anything;
// pp = anything;
// cc = anything;
// dd = anything;
// ee = anything;
// }

ASNode* Parser::ParseListDefine( const Token& tk , bool* status ) {
	ParsingTerminator term;
	term.AddTerminator(Token::TT_END);
	*status = true;
	assert( tk.token() == Token::TT_LLBRACKET );
	NodeDefineList* ret = new NodeDefineList();
	// Now parsing elements one by one.
	while(true) {
		ASNode* each = ParseListAssignment(status);
		ERROR_CHECK(delete ret;);
		ret->AppendDefinition(each);
		Token ntk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
		if( ntk.token() == Token::TT_RLBRACKET ) {
			break;
		}
	}
	EXPECT(Token::TT_RLBRACKET);
	return ret;
}

// Right hand side value can be:
// 1) A function definition 
// 2) A list definition
// 3) A expression 
ASNode* Parser::ParseRightHandSideValue( const ParsingTerminator& term , bool* status ) {
	Token tk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	switch(tk.token()){
	case Token::TT_FUNCTION:
		return ParseFunctionDefine(scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE ),status);
	case Token::TT_LLBRACKET:
		return ParseListDefine(scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE ), status );
	case Token::TT_NULL:
		return new NodeNull();
	default:
		ASNode* ret = ParseExpression(term,status);
		ERROR_CHECK(VOID_OP);
		return ret;
	}
}
// Assignment will not consume the terminator characters.
// This is the same as expression. The terminator character
// is ';', which must be consumes by the caller function !
ASNode* Parser::ParseVarDeclarationOrWithAssignment( const ParsingTerminator& term , bool* status , bool ensure_assignment ){
	*status = true;
	ASNode* lh = ParseVarDeclarationOrLeftHandSideValue(status);
	ERROR_CHECK(VOID_OP);
	if( !ensure_assignment ) {
		// We are not allowed to consume this terminator
		Token tk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
		if( tk.token() == Token::TT_END ) {
			// When reach here, it means that this operation is a
			// declaration. We are allowed to exit here .
			return lh;
		}
	}
	// When reach here means that the user requires that
	// a var declaration will followed by a assignment
	// expression (RightHandSideValue).
	Token tk = scanner_.Advance(Scanner::MODE_IGNORE_WHITESPACE);
	if( tk.token() != Token::TT_ASSIGN ) {
		*status  = false;
		ReportError("Expect \"=\"");
		delete lh;
		return NULL;
	}
	ASNode* rh = ParseRightHandSideValue(term,status);
	ERROR_CHECK(VOID_OP);
	NodeAssignment* assignment = new NodeAssignment();
	assignment->set_left_child(lh);
	assignment->set_right_child(rh);
	return assignment;
}

ASNode* Parser::ParseControlKeyword( bool* status ) {
	Token token = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	assert( ParserHelper::IsControlKeyword(token.token()) );
	NodeKeyword* ret = new NodeKeyword();
	ret->set_token(token.token());
	token = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	if( token.token() != Token::TT_END ) {
		*status = false;
		ReportError("Expected \";\"");
		delete ret;
		return NULL;
	}
	return ret;
}

// Statement is the building block of codeblock
// A statement can be 
// 1) assignment  2) expression  3) var declaration
ASNode* Parser::ParseStatement( bool* status ) {
	ParsingTerminator term;
	term.AddTerminator(Token::TT_END);
	ASNode* ret;
	Token tk = scanner_.Peek( Scanner::MODE_IGNORE_WHITESPACE );
	switch(tk.token() ) {
		// Assignment 
	case Token::TT_VAR:
	case Token::TT_GLOBAL:
	case Token::TT_SYMBOL:
		ret= ParseVarDeclarationOrWithAssignment(term,status,false);
		ERROR_CHECK(VOID_OP);
		EXPECT(Token::TT_END);
		return ret;
	default:
		// Expression 
		ParsingTerminator terminator;
		terminator.AddTerminator( Token::TT_END );
		ASNode* exp = ParseExpression(terminator,status);
		ERROR_CHECK(VOID_OP);
		EXPECT(Token::TT_END);
		return exp;
	}
}
ASNode* Parser::ParseChunk( bool* status ) {
	Token tk = scanner_.Advance( Scanner::MODE_IGNORE_WHITESPACE );
	assert(tk.token() == Token::TT_LLBRACKET);
	// Once we enter the codeblock, we should change
	// the variable scope. 
	ParserScope::ParserScopeAuto auto_scope(scope_);
	
	NodeChunk* codeblock = new NodeChunk();

	while( true ) {
		ASNode* statement = ParseStatement(status);
		ERROR_CHECK(delete codeblock;);
		codeblock->AppendStatement( statement );

		Token ntk = scanner_.Peek(Scanner::MODE_IGNORE_WHITESPACE);
		switch( ntk.token() ) {
		case Token::TT_RLBRACKET:
			EXPECT(Token::TT_RLBRACKET);
			goto finish;
		case Token::TT_RETURN: {
				// This means there exists an return statement
				// Since this function will only be used when 
				// parsing a function definition or control statement.
				// Therefore, we are safe to declare such statement here.
				EXPECT(Token::TT_RETURN);
				ASNode* return_node = ParseReturn(ntk,status);
				ERROR_CHECK(delete codeblock;);
				EXPECT(Token::TT_RLBRACKET);
				// Append the last return statement
				codeblock->AppendStatement(return_node);
				// Any subsequent code is illegal
				ntk = scanner_.Peek(Scanner::MODE_IGNORE_WHITESPACE);
				if( ntk.token() != Token::TT_RLBRACKET ) {
					delete codeblock;
					*status = false;
					ReportError("Node code should be written after return statement.");
					return NULL;
				}
				goto finish; 
			}
		default:
			if( ParserHelper::IsControlKeyword(tk.token()) ) {
				ASNode* keyword = ParseControlKeyword(status);
				ERROR_CHECK(delete codeblock;);
				EXPECT(Token::TT_END);
				codeblock->AppendStatement(keyword);
			}
			break;
		}
	}
finish:
	return codeblock;
}

}// namespace internal
}// namespace sscript
